#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
操作播放器模块
负责重复执行录制的鼠标和键盘操作
"""

import time
import threading
from pynput import mouse, keyboard
from pynput.mouse import Button
from pynput.keyboard import Key


class OperationPlayer:
    """操作播放器类"""
    
    def __init__(self):
        self.is_playing = False
        self.should_stop = False
        
        # 控制器
        self.mouse_controller = mouse.Controller()
        self.keyboard_controller = keyboard.Controller()
        
        # 播放设置
        self.speed_multiplier = 1.0  # 播放速度倍数
        self.pause_between_loops = 1.0  # 循环间隔（秒）
    
    def play_operations(self, operations, loop_count=1, stop_callback=None):
        """播放操作序列
        
        Args:
            operations: 操作列表
            loop_count: 循环次数
            stop_callback: 停止回调函数，返回True时停止播放
        """
        if not operations:
            print("没有操作可播放")
            return
        
        self.is_playing = True
        self.should_stop = False
        
        print(f"开始播放操作，循环 {loop_count} 次")
        
        try:
            for loop_index in range(loop_count):
                if self.should_stop or (stop_callback and stop_callback()):
                    break
                
                print(f"执行第 {loop_index + 1}/{loop_count} 次循环")
                
                # 播放一次操作序列
                self._play_single_sequence(operations, stop_callback)
                
                # 如果不是最后一次循环，等待间隔时间
                if loop_index < loop_count - 1 and not self.should_stop:
                    if stop_callback and stop_callback():
                        break
                    time.sleep(self.pause_between_loops)
            
            print("播放完成")
        
        except Exception as e:
            print(f"播放过程中出错: {e}")
        
        finally:
            self.is_playing = False
    
    def _play_single_sequence(self, operations, stop_callback=None):
        """播放单次操作序列"""
        if not operations:
            return
        
        start_time = time.time()
        last_timestamp = 0
        
        for operation in operations:
            if self.should_stop or (stop_callback and stop_callback()):
                break
            
            # 计算等待时间
            current_timestamp = operation['timestamp']
            wait_time = (current_timestamp - last_timestamp) / self.speed_multiplier
            
            if wait_time > 0:
                time.sleep(wait_time)
            
            # 执行操作
            self._execute_operation(operation)
            
            last_timestamp = current_timestamp
    
    def _execute_operation(self, operation):
        """执行单个操作"""
        try:
            op_type = operation['type']
            
            if op_type == 'mouse_move':
                self._execute_mouse_move(operation)
            elif op_type == 'mouse_click':
                self._execute_mouse_click(operation)
            elif op_type == 'mouse_scroll':
                self._execute_mouse_scroll(operation)
            elif op_type == 'key_press':
                self._execute_key_press(operation)
            elif op_type == 'key_release':
                self._execute_key_release(operation)
            else:
                print(f"未知操作类型: {op_type}")
        
        except Exception as e:
            print(f"执行操作失败: {e}, 操作: {operation}")
    
    def _execute_mouse_move(self, operation):
        """执行鼠标移动"""
        x, y = operation['x'], operation['y']
        self.mouse_controller.position = (x, y)
    
    def _execute_mouse_click(self, operation):
        """执行鼠标点击"""
        x, y = operation['x'], operation['y']
        button_name = operation['button']
        pressed = operation['pressed']
        
        # 移动到目标位置
        self.mouse_controller.position = (x, y)
        
        # 转换按钮名称
        button = self._string_to_button(button_name)
        
        if pressed:
            self.mouse_controller.press(button)
        else:
            self.mouse_controller.release(button)
    
    def _execute_mouse_scroll(self, operation):
        """执行鼠标滚轮"""
        x, y = operation['x'], operation['y']
        dx, dy = operation['dx'], operation['dy']
        
        # 移动到目标位置
        self.mouse_controller.position = (x, y)
        
        # 执行滚轮操作
        self.mouse_controller.scroll(dx, dy)
    
    def _execute_key_press(self, operation):
        """执行按键按下"""
        key_name = operation['key']
        key = self._string_to_key(key_name)
        
        if key:
            self.keyboard_controller.press(key)
    
    def _execute_key_release(self, operation):
        """执行按键释放"""
        key_name = operation['key']
        key = self._string_to_key(key_name)
        
        if key:
            self.keyboard_controller.release(key)
    
    def _string_to_button(self, button_name):
        """将字符串转换为鼠标按钮"""
        button_map = {
            'left': Button.left,
            'right': Button.right,
            'middle': Button.middle
        }
        return button_map.get(button_name, Button.left)
    
    def _string_to_key(self, key_name):
        """将字符串转换为按键"""
        if not key_name:
            return None
        
        # 单字符按键
        if len(key_name) == 1:
            return key_name
        
        # 特殊按键映射
        special_keys = {
            'space': Key.space,
            'enter': Key.enter,
            'tab': Key.tab,
            'shift': Key.shift,
            'shift_l': Key.shift_l,
            'shift_r': Key.shift_r,
            'ctrl': Key.ctrl,
            'ctrl_l': Key.ctrl_l,
            'ctrl_r': Key.ctrl_r,
            'alt': Key.alt,
            'alt_l': Key.alt_l,
            'alt_r': Key.alt_r,
            'cmd': Key.cmd,
            'cmd_l': Key.cmd_l,
            'cmd_r': Key.cmd_r,
            'esc': Key.esc,
            'escape': Key.esc,
            'backspace': Key.backspace,
            'delete': Key.delete,
            'home': Key.home,
            'end': Key.end,
            'page_up': Key.page_up,
            'page_down': Key.page_down,
            'up': Key.up,
            'down': Key.down,
            'left': Key.left,
            'right': Key.right,
            'f1': Key.f1,
            'f2': Key.f2,
            'f3': Key.f3,
            'f4': Key.f4,
            'f5': Key.f5,
            'f6': Key.f6,
            'f7': Key.f7,
            'f8': Key.f8,
            'f9': Key.f9,
            'f10': Key.f10,
            'f11': Key.f11,
            'f12': Key.f12,
            'caps_lock': Key.caps_lock,
            'num_lock': Key.num_lock,
            'scroll_lock': Key.scroll_lock,
            'print_screen': Key.print_screen,
            'pause': Key.pause,
            'insert': Key.insert
        }
        
        return special_keys.get(key_name.lower(), key_name)
    
    def stop_playing(self):
        """停止播放"""
        self.should_stop = True
        print("停止播放操作")
    
    def set_speed_multiplier(self, multiplier):
        """设置播放速度倍数
        
        Args:
            multiplier: 速度倍数，1.0为正常速度，2.0为2倍速，0.5为半速
        """
        if multiplier > 0:
            self.speed_multiplier = multiplier
            print(f"播放速度设置为: {multiplier}x")
    
    def set_pause_between_loops(self, pause_time):
        """设置循环间隔时间
        
        Args:
            pause_time: 间隔时间（秒）
        """
        if pause_time >= 0:
            self.pause_between_loops = pause_time
            print(f"循环间隔设置为: {pause_time}秒")
    
    def get_status(self):
        """获取播放器状态"""
        return {
            'is_playing': self.is_playing,
            'should_stop': self.should_stop,
            'speed_multiplier': self.speed_multiplier,
            'pause_between_loops': self.pause_between_loops
        }
    
    def play_operations_async(self, operations, loop_count=1, stop_callback=None, 
                            completion_callback=None):
        """异步播放操作序列
        
        Args:
            operations: 操作列表
            loop_count: 循环次数
            stop_callback: 停止回调函数
            completion_callback: 完成回调函数
        """
        def play_thread():
            try:
                self.play_operations(operations, loop_count, stop_callback)
            finally:
                if completion_callback:
                    completion_callback()
        
        thread = threading.Thread(target=play_thread)
        thread.daemon = True
        thread.start()
        return thread
    
    def validate_operations(self, operations):
        """验证操作序列的有效性
        
        Args:
            operations: 操作列表
            
        Returns:
            tuple: (is_valid, error_message)
        """
        if not operations:
            return False, "操作列表为空"
        
        required_fields = {
            'mouse_move': ['type', 'x', 'y', 'timestamp'],
            'mouse_click': ['type', 'x', 'y', 'button', 'pressed', 'timestamp'],
            'mouse_scroll': ['type', 'x', 'y', 'dx', 'dy', 'timestamp'],
            'key_press': ['type', 'key', 'timestamp'],
            'key_release': ['type', 'key', 'timestamp']
        }
        
        for i, operation in enumerate(operations):
            if not isinstance(operation, dict):
                return False, f"操作 {i} 不是字典类型"
            
            op_type = operation.get('type')
            if op_type not in required_fields:
                return False, f"操作 {i} 类型无效: {op_type}"
            
            # 检查必需字段
            for field in required_fields[op_type]:
                if field not in operation:
                    return False, f"操作 {i} 缺少字段: {field}"
            
            # 检查时间戳
            timestamp = operation.get('timestamp')
            if not isinstance(timestamp, (int, float)) or timestamp < 0:
                return False, f"操作 {i} 时间戳无效: {timestamp}"
        
        return True, "操作序列有效"